package ncc.bs.Plugins;

import java.text.SimpleDateFormat;
import java.util.*;

import ncc.bs.utils.GetParamConfigUtil;
import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.itf.pub.dbservice.IDBService;
import nc.itf.pub.dbservice.INCPushCZService;
import nc.jdbc.framework.generator.IdGenerator;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.vo.pub.BusinessException;
import nccloud.bs.log.LogVO;
import nccloud.utils.baseapp.HttpReqUtils;
import nccloud.utils.baseapp.InitParamUtils;
import nccloud.utils.baseapp.MessageLogger;
import nccloud.utils.baseapp.ToolUtils;

/**
 * <p>同步财政系统</p>
 *  单位会计科目信息
 * @author Administrator
 * @date 2024年2月27日
 */
public class AccountingSubjectBackGroundWorkPlugin extends AbstractBackgroundWorkPlugin{
	private BaseDAO dao;
	private final SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
	private final SimpleDateFormat ymdsfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private IDBService dbService;
	private INCPushCZService ncPushCZService;

	@SuppressWarnings("rawtypes")
	@Override
	public void doBusiness(Map keyMap) throws BusinessException {
		List<Map<String, Object>> lists = queryData(buildSQL(keyMap));
		try {
			if(lists == null ) return;
			// 对分组的数据进行推送
			for(Map<String, Object> MParam : lists) {
				List<LogVO> listVOs = new ArrayList<>();
				String message = null;
				String issuccess = "Y";
				String result = null;
				try {
					JSONArray kjparam = buildParam(MParam,listVOs, keyMap);
					String param = super.getParam(kjparam,"DWKJHS03", super.getAppid()); // 每十行数据合并在一起推送
					if(param == null || "".equals(param)) return;
					result = HttpReqUtils.sendPost(getURL("DEF001"), param);
					MessageLogger.info("----第四步接口响应结果::" + result);
					JSONObject jsonres = JSONObject.parseObject(result);
					Object code = jsonres.get("code");
					if("200".equals(code)) {
						message = "同步成功";
					}else {
						message = jsonres.getString("msg");
						issuccess = "N";
						result = jsonres.toString();
					}

				}catch(Exception e) {
					message = e.getMessage();
					issuccess = "N";
				}finally {
					for(LogVO vo : listVOs) {
						vo.setIssuccess(issuccess);
						vo.setError(message);
						vo.setVdef2(result);
						vo.setDr("0");
					}

					getDbService().insertVOList(listVOs);
				}
			}
		}catch(Exception e) {
			LogVO vo = new LogVO();
			vo.setPk_id(NCLocator.getInstance().lookup(IdGenerator.class).generate());
			vo.setIssuccess("N");
			vo.setPk_group("0001A210000000000JB9");
			vo.setPk_billtypeid("accountSubject");
			vo.setSystem_flag("financial");
			vo.setVdef1("拉取参数、类型:"+ keyMap.get("type")+",开始日期:"+keyMap.get("begindate")+"结束日期:"+keyMap.get("enddate")+",同步频率:"+keyMap.get("synctime"));
			vo.setError("会计科目同步:"+e.getMessage());
			getDbService().insertVO(vo);
		}
	}

	/**
	 * 查询需要同步的数据
	 * @param sql
	 * @return
	 * @throws BusinessException
	 */
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>>  queryData(String sql)  throws BusinessException{
		if(sql == null) return null;
		List<Map<String, Object>> lists = (List<Map<String, Object>>)getDao().executeQuery(sql, new MapListProcessor());
		return lists == null ||  lists.isEmpty() ? null : lists;
	}

	/**
	 * 构建数据查询sql
	 * @return
	 * @throws BusinessException
	 */
	@SuppressWarnings("rawtypes")
	public String buildSQL(Map keyMap) throws BusinessException{
		StringBuilder sb = new StringBuilder();
		if(keyMap != null && !keyMap.isEmpty()) {
			sb.append("  SELECT \n" );
			sb.append("        kjkmjbxx.pk_account id, \n"  );
			sb.append("        kmb.pk_accchart, kjkm.pk_account,\n"  );
			sb.append("        og.code groupCode, \n"  );
			sb.append("        og.name groupName, \n"  );
			sb.append("        oos.code orgCode, \n"  );
			sb.append("        oos.name orgName, \n"  );
			sb.append("        kmtx.code kmtxCode, \n"  );
			sb.append("        kmtx.name kmtxName, \n"  );
			sb.append("        case when bc.code is null  then 0 when bc.code = 'CNY' then 0 else 1 end IS_CUR, ");
			sb.append("        case kjkmjbxx.quantity when 'N' then 0 else 1 end IS_QTY,  ");
			sb.append("        kjkmjbxx.code kjkmjbxxCode, \n"  );
			sb.append("        case when kjkm.name <> '~' then kjkm.name else kjkmjbxx.name end kjkmName , \n"  );
			sb.append("        case when kjkmjbxx.enablestate = 2 then 1 else 2 end enablestate,    \n"  );
			sb.append("        case when kjkmjbxx.dr = 0 then 2 else 1 end dr, \n"  );
			sb.append("        case when kjkm.endflag = 'Y' then 1 else 0 end flag ,   \n"  );
			sb.append("        kjkmjbxx.pid fid,    \n"  );
			sb.append("        kjkmjbxx.acclev,     \n"  );
			sb.append("        kmlx.code kmlxcode,     \n"  );
			sb.append("        kmlx.name kmlxname, \n"  );
			sb.append("        case when kjkmjbxx.balanorient = 0  then 1 else  2 end balanorient ,     \n"  );
			sb.append("        kjkm.CREATIONTIME, \n"  );
			sb.append("        bc.code currtypecode,  \n"  );
			sb.append("        bc.name currtypename,  \n"  );
			sb.append("        kjkmjbxx.ts,  \n"  );
			sb.append("        kjkm.usedesc        \n"  );
			sb.append(" FROM \n"  );
			sb.append(" bd_accsystem kmtx   \n"  );
			sb.append(" LEFT JOIN bd_accchart kmb on kmtx.pk_accsystem = kmb.pk_accsystem \n"  );
			sb.append(" LEFT JOIN bd_accasoa kjkm on kmb.pk_accchart = kjkm.pk_accchart \n"  );
			sb.append(" LEFT JOIN bd_account kjkmjbxx ON kjkm.pk_account = kjkmjbxx.pk_account \n"  );
			sb.append(" LEFT JOIN org_orgs oos on oos.pk_org = kmb.pk_org \n"  );
			sb.append(" LEFT JOIN org_group og on oos.pk_group = og.pk_group \n"  );
			sb.append(" LEFT JOIN bd_acctype kmlx on kmlx.pk_acctype = kjkmjbxx.pk_acctype \n"  );
			sb.append(" left join bd_currtype bc on kjkm.currency = bc.pk_currtype  \n"  );
			sb.append(" where 1 = 1 \n"  );
			if (null != keyMap.get("pk_account")) {
				sb.append(" and kjkmjbxx.pk_account in ('" + StringUtils.join(keyMap.get("pk_account").toString().split(","), "','") + "') \n");
			}
			if (null != keyMap.get("pid")) {
				sb.append(" and kjkmjbxx.pid in ('" + StringUtils.join(keyMap.get("pid").toString().split(","), "','") + "') \n");
			}
			if (null == keyMap.get("kmtxcode")) {
				sb.append(" and kmtx.code ='9001' ");
			} else {
				sb.append(" and kmtx.code in ('" + StringUtils.join(keyMap.get("kmtxcode").toString().split(","), "','") + "') \n");
			}
			if (null == keyMap.get("kmbcode")) {
				sb.append(" and kmb.code = '001' ");
			} else {
				sb.append(" and kmb.code in ('" + StringUtils.join( keyMap.get("kmbcode").toString().split(","), "','") + "') \n");
			}
			Object startdate = null;
			Object stopdate = null;
			Object type = keyMap.get("type");
			if("1".equals(type)) { //  [指定时间段拉取,1];[拉指定的一天,2];
				Object begindate = keyMap.get("begindate")  == null  ? ymd.format(new Date()) : keyMap.get("begindate") ;
				Object enddate = keyMap.get("enddate") == null  ? ymd.format(new Date()) : keyMap.get("enddate") ;
				startdate = begindate + " 00:00:00";
				stopdate = enddate + " 23:59:59";
			}else if("2".equals(type)) { // [拉指定的一天,2]
				Object begindate = keyMap.get("begindate") == null  ? ymd.format(new Date()) : keyMap.get("begindate") ;
				startdate = begindate + " 00:00:00";
				stopdate = begindate + " 23:59:59";
			}else { // [定时执行, ] 默认同步频率30分钟  
				Calendar calendar = Calendar.getInstance();
				stopdate = ymdsfm.format(calendar.getTime());//当前时间
				Object synctime = keyMap.get("synctime"); //  同步频率
				if(synctime ==  null ) {
					calendar.add(Calendar.MINUTE, -30); // time 的前几分钟
				}else {
					int time = Integer.parseInt(synctime.toString());
					calendar.add(Calendar.MINUTE, -time); // time 的前几分钟
				}
				startdate = ymdsfm.format(calendar.getTime());
			}
//			sb.append("and kjkmjbxx.ts between '"+startdate+"' and '"+stopdate+"' \n"  );
			sb.append("order by kjkmjbxx.code asc ");
			return sb.toString();
		}
		return null;
	}

	/**
	 * 构建请求参数
	 * @return
	 * @throws Exception
	 */
	public JSONArray buildParam(Map<String, Object> map,List<LogVO> listVOs,Map keyMap) throws Exception{
		JSONArray jsonArray = new JSONArray();
		String year = ymd.format(new Date()).split("-")[0];
		JSONObject json = new JSONObject();
		String ACCOUNT_CLS_ID = map.get("id")+year;
		Object PARENT_ID = map.get("fid") == null ? "0" :map.get("fid")+year;
		json.put("ACCT_SET_NAME", super.getACCT_SET_NAME());  // 账套名称
		json.put("AGENCY_NAME", super.getAGENCY_NAME()); // 单位名称
		json.put("ACCOUNT_CLS_ID", ACCOUNT_CLS_ID);  // 帐套唯一标识
		json.put("MOF_DIV_CODE", super.getMOF_DIV_CODE());  // 财政区划代码
		json.put("ACCT_SET_CODE", super.getAccount());  // 账套编号
		json.put("SET_YEAR", year); // // 会计年度
		json.put("AGENCY_CODE", super.getUnit()); // 单位代码
		json.put("GOV_ACCT_CLS_CODE", ToolUtils.getJudgeAttribute(map.get("kjkmjbxxcode"))); // 单位会计科目代码
		json.put("CODE", ToolUtils.getJudgeAttribute(map.get("kjkmjbxxcode"))); // 单位会计科目代码
		json.put("GOV_ACCT_CLS_NAME", ToolUtils.getJudgeAttribute(map.get("kjkmname"))); // 单位会计科目名称
		json.put("PARENT_ID", PARENT_ID); // 父级唯一标识
		json.put("LEVEL_NO", map.get("acclev") == null ? 1 :map.get("acclev")); // 级次
		json.put("IS_LEAF", map.get("kjkmendflag") == null ? "0" :map.get("kjkmendflag")); // 是否末级
		json.put("IS_ENABLED", map.get("enablestate") == null ? 1 :map.get("enablestate")); // 0 停用  1 启用
		json.put("BALANCE_DIR", map.get("balanorient") ); // 余额方向
		json.put("GOV_ACCT_CLS_ENUM_CODE", ToolUtils.getJudgeAttribute(map.get("kmlxcode"))); // 单位会计科目类型代码
		json.put("EXECUTIVE_ACC", 11); // 执行会计制度类型
		json.put("AGENCY_TYPE_CODE", 11); // 单位类型
		json.put("CURRENCY_CODE", map.get("currtypecode") == null ? "CNY" :map.get("currtypecode")); // 币种代码
		json.put("CURRENCY_NAME", map.get("currtypename") == null ? "人民币" :map.get("currtypename")); //
		json.put("IS_CUR", map.get("is_cur")); // 是否外币核算
		json.put("IS_QTY", map.get("is_qty")); // 是否数量核算
		json.put("REMARK", ToolUtils.getJudgeAttribute(map.get("remark"))); // 说明
		json.put("UPDATE_TIME", super.getYMDHMS(map.get("ts"))); // 更新时间
		json.put("CREATE_TIME", super.getYMDHMS(map.get("creationtime")));
		json.put("IS_DELETED", map.get("dr")); // 1已删除 2 未删除
		json.put("IS_STANDARD", 0); // 0标准代码集 1扩展代码集
		json.put("ELEMENT_CODE", getAccAss(map.get("pk_accchart"), map.get("pk_account"))); // 使用的辅助核算类别
		LogVO logVO = getDbService().buildLogVO(map, json, "financial", "accountSubject");
		listVOs.add(logVO);
		jsonArray.add(json);
		return jsonArray ;
	}

	/**
	 * 获取会计科目下面的辅助
	 * @param pk_accchart  科目表主键
	 * @param pk_account 会计科目主键盘
	 * @return
	 * @throws BusinessException
	 */
	@SuppressWarnings("unchecked")
	protected String getAccAss(Object pk_accchart, Object pk_account) throws BusinessException {
		if(pk_accchart == null || pk_account == null) return "";
		String sql = "	select distinct b.code " +
				"	from bd_accass a inner join bd_accassitem b on a.pk_entity = b.pk_accassitem " +
				"	and a.pk_accasoa in( " +
				"	  select pk_accasoa from bd_accasoa where pk_accasoa in " +
				"                 (select pk_accasoa " +
				"                    from bd_account, bd_accasoa bd_accasoa " +
				"                     	where bd_account.pk_account = bd_accasoa.pk_account " +
				"                     and bd_accasoa.pk_accchart = '" + pk_accchart + "' " +
				"                     and bd_account.pk_account = '" + pk_account + "' )  " +
				")";
		List<String> lists = (List<String>)getDao().executeQuery(sql, new ColumnListProcessor());
		if(lists == null || lists.isEmpty()) return "";
		// 当前为财政系统所需要的辅助核算项目
		String defListCode = "HRP_CZ_FZHS";
		// 获取自定义档案中维护的档案对照关系
		String dzSQL = "SELECT\n" +
				"\tdef.code,def.name, def.SHORTNAME,def.MEMO\n" +
				"FROM\n" +
				"\tbd_defdoc def \n" +
				"LEFT JOIN BD_DEFDOCLIST defli on def.PK_DEFDOCLIST = defli.PK_DEFDOCLIST\n" +
				"WHERE\n" +
				"\tdefli.code = '"+defListCode+"'\n" +
				"\tAND ( 1 = 1 AND 1 = 1 AND ( def.enablestate = 2 ) ) \n" +
				"\tAND ( ( def.pk_group = '0001A210000000000JB9' ) ) \n" +
				"ORDER BY code";
		List<Map<String,Object>> dzlists = (List<Map<String,Object>>)this.getDao().executeQuery(dzSQL, new MapListProcessor());
		if (dzlists == null || dzlists.isEmpty()) return "";
		String czCode = "";
		for (String ncCode : lists) {
			for (Map<String, Object> dzmap : dzlists) {
				if (ncCode.equals(dzmap.get("code").toString())){ // 维护了对照
					czCode += "," +dzmap.get("shortname");
				}
			}
		}
		return  "".equals(czCode) ? "" : czCode.substring(1);
	}

	/**
	 * 获取第三方同步地址
	 * @param initCode
	 * @return
	 * @throws Exception
	 */
	public String getURL(String initCode) throws Exception{
		String url = InitParamUtils.getOrgParam("GLOBLE00000000000000",initCode)+"/pty/gla-dec/v1/account/accountclses";
		MessageLogger.info("----第三步接口请求地址:" + url);
		return url;
	}

	/**
	 * 数据库操作服务
	 * @return
	 */
	public IDBService getDbService() {
		if(dbService == null) {
			dbService = NCLocator.getInstance().lookup(IDBService.class);
		}
		return dbService;
	}

	public INCPushCZService getNcPushCZService() {
		if(null == this.ncPushCZService) {
			this.ncPushCZService = NCLocator.getInstance().lookup(INCPushCZService.class);
		}
		return this.ncPushCZService;
	}
	public BaseDAO getDao() {
		return dao == null ? new BaseDAO() : dao ;
	}
}